/**
 *  @file Translate.c
 *  @desc 演示单链表的基本操作：尾插、正向打印、递归反向打印（类似翻转）、内存释放
 *  @author WangBlue(wangjiping596@gmail.com)
 *  @date 2025-07-11 10:47
 *  @version 1.0
 */

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>

// ------------------------- 链表结构定义 -------------------------

/**
 * @brief 单链表结点结构体定义
 */
typedef struct node {
    int data;              ///< 数据域
    struct node *next;     ///< 指针域
} node, *link;

// ------------------------- 链表基本操作函数 -------------------------

/**
 * @brief 创建一个新节点
 * @param value 数据值
 * @return 返回新结点指针，失败返回 NULL
 */
link createNode(int value) {
    link node = (link) malloc(sizeof(node));
    if (node == NULL) return NULL;

    node->next = NULL;
    node->data = value;
    return node;
}

/**
 * @brief 初始化链表（带头结点）
 * @param head 指向头指针的指针
 */
void initNode(link *head) {
    link node = (link) malloc(sizeof(node));
    if (node == NULL) return;
    node->data = 0;        // 头结点的数据通常无意义
    node->next = NULL;
    *head = node;
}

/**
 * @brief 尾插法插入数据节点
 * @param head 链表头指针（带头结点）
 * @param value 要插入的值
 */
void insertTail(link head, int value) {
    link node = createNode(value);
    if (node == NULL) return;

    link cur = head;
    // 遍历至链表末尾
    while (cur->next != NULL) {
        cur = cur->next;
    }
    cur->next = node;
}

/**
 * @brief 正向打印链表数据（跳过头结点）
 * @param head 链表头指针
 */
void printList(link head) {
    if (head == NULL || head->next == NULL) return;

    link cur = head->next; // 跳过头结点
    while (cur != NULL) {
        printf("value is %d\n", cur->data);
        cur = cur->next;
    }
    printf("\n");
}

/**
 * @brief 使用递归的方式逆序打印链表（不修改结构，仅逆序输出）
 * @param head 链表头指针
 */
void translatePrint(link head) {
    if (head == NULL || head->next == NULL) return;

    link cur = head->next; // 跳过头结点
    translatePrint(head->next);  // 递归调用，进入下一层
    printf("value is %d\n", cur->data); // 回溯时打印，实现逆序输出
}

/**
 * @brief 释放链表所有结点（保留头结点，但头结点 next 置空）
 * @param head 指向链表头指针的指针
 */
void destroy(link *head) {
    if (*head == NULL || (*head)->next == NULL) {
        return;
    }

    link cur = (*head)->next;
    while (cur != NULL) {
        link temp = cur->next; // 保存下一节点
        free(cur);             // 释放当前节点
        cur = temp;            // 移动到下一节点
    }

    (*head)->next   = NULL; // 将头结点 next 指向 NULL
}

// ------------------------- 主函数测试 -------------------------

int main() {
    link head = NULL;

    // 初始化链表
    initNode(&head);

    // 插入数据：1 → 2 → 3
    insertTail(head, 1);
    insertTail(head, 2);
    insertTail(head, 3);

    // 正向打印链表
    printf("正向输出链表:\n");
    printList(head);

    // 逆序打印链表（不改变结构）
    printf("逆序输出链表:\n");
    translatePrint(head);

    // 释放内存
    destroy(&head);

    // 再次打印（应无输出）
    printf("释放后链表内容:\n");
    printList(head);

    return 0;
}
